home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / qe4 / xy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-11  |  20.3 KB  |  953 lines

  1.  
  2. #include "qe3.h"
  3.  
  4. #define    PAGEFLIPS    2
  5.  
  6. /*
  7. ============
  8. XY_Init
  9. ============
  10. */
  11. void XY_Init (void)
  12. {
  13.     g_qeglobals.d_xy.origin[0] = 0;
  14.     g_qeglobals.d_xy.origin[1] = 20;
  15.     g_qeglobals.d_xy.origin[2] = 46;
  16.  
  17.     g_qeglobals.d_xy.scale = 1;
  18. }
  19.  
  20.  
  21. /*
  22. ============================================================================
  23.  
  24.   MOUSE ACTIONS
  25.  
  26. ============================================================================
  27. */
  28.  
  29. static    int    cursorx, cursory;
  30. static    int    buttonstate;
  31. static    int    pressx, pressy;
  32. static    vec3_t    pressdelta;
  33. static    qboolean    press_selection;
  34.  
  35. void XY_ToPoint (int x, int y, vec3_t point)
  36. {
  37.     point[0] = g_qeglobals.d_xy.origin[0] + (x - g_qeglobals.d_xy.width/2)/g_qeglobals.d_xy.scale;
  38.     point[1] = g_qeglobals.d_xy.origin[1] + (y - g_qeglobals.d_xy.height/2)/g_qeglobals.d_xy.scale;
  39.     point[2] = 0;
  40. }
  41.  
  42. void XY_ToGridPoint (int x, int y, vec3_t point)
  43. {
  44.     point[0] = g_qeglobals.d_xy.origin[0] + (x - g_qeglobals.d_xy.width/2)/g_qeglobals.d_xy.scale;
  45.     point[1] = g_qeglobals.d_xy.origin[1] + (y - g_qeglobals.d_xy.height/2)/g_qeglobals.d_xy.scale;
  46.     point[2] = 0;
  47.     point[0] = floor(point[0]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  48.     point[1] = floor(point[1]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  49. }
  50.  
  51. /*
  52. ==============
  53. XY_MouseDown
  54. ==============
  55. */
  56. void XY_MouseDown (int x, int y, int buttons)
  57. {
  58.     vec3_t    point;
  59.     vec3_t    origin, dir, right, up;
  60.  
  61.     buttonstate = buttons;
  62.     pressx = x;
  63.     pressy = y;
  64.     VectorCopy (vec3_origin, pressdelta);
  65.  
  66.     XY_ToPoint (x, y, point);
  67.  
  68.     VectorCopy (point, origin);
  69.     origin[2] = 8192;
  70.  
  71.     dir[0] = 0; dir[1] = 0; dir[2] = -1;
  72.     right[0] = 1/g_qeglobals.d_xy.scale; right[1] = 0; right[2] = 0;
  73.     up[0] = 0; up[1] = 1/g_qeglobals.d_xy.scale; up[2] = 0;
  74.  
  75.     press_selection = (selected_brushes.next != &selected_brushes);
  76.  
  77.     Sys_GetCursorPos (&cursorx, &cursory);
  78.  
  79.     // lbutton = manipulate selection
  80.     // shift-LBUTTON = select
  81.     if ( (buttons == MK_LBUTTON)
  82.         || (buttons == (MK_LBUTTON | MK_SHIFT))
  83.         || (buttons == (MK_LBUTTON | MK_CONTROL))
  84.         || (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) )
  85.     {    
  86.         Drag_Begin (x, y, buttons, 
  87.             right, up,
  88.             origin, dir);
  89.         return;
  90.     }
  91.  
  92.     // control mbutton = move camera
  93.     if (buttonstate == (MK_CONTROL|MK_MBUTTON) )
  94.     {    
  95.         camera.origin[0] = point[0];
  96.         camera.origin[1] = point[1];
  97.         Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
  98.     }
  99.  
  100.     // mbutton = angle camera
  101.     if (buttonstate == MK_MBUTTON)
  102.     {    
  103.         VectorSubtract (point, camera.origin, point);
  104.         if (point[1] || point[0])
  105.         {
  106.             camera.angles[YAW] = 180/Q_PI*atan2 (point[1], point[0]);
  107.             Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
  108.         }
  109.     }
  110.  
  111.     // shift mbutton = move z checker
  112.     if (buttonstate == (MK_SHIFT|MK_MBUTTON) )
  113.     {
  114.         XY_ToPoint (x, y, point);
  115.         z.origin[0] = point[0];
  116.         z.origin[1] = point[1];
  117.         Sys_UpdateWindows (W_XY_OVERLAY|W_Z);
  118.         return;
  119.     }
  120.  
  121. }
  122.  
  123. /*
  124. ==============
  125. XY_MouseUp
  126. ==============
  127. */
  128. void XY_MouseUp (int x, int y, int buttons)
  129. {
  130.     Drag_MouseUp ();
  131.  
  132.     if (!press_selection)
  133.         Sys_UpdateWindows (W_ALL);
  134.  
  135.     buttonstate = 0;
  136. }
  137.  
  138. qboolean DragDelta (int x, int y, vec3_t move)
  139. {
  140.     vec3_t    xvec, yvec, delta;
  141.     int        i;
  142.  
  143.     xvec[0] = 1/g_qeglobals.d_xy.scale;
  144.     xvec[1] = xvec[2] = 0;
  145.     yvec[1] = 1/g_qeglobals.d_xy.scale;
  146.     yvec[0] = yvec[2] = 0;
  147.  
  148.     for (i=0 ; i<3 ; i++)
  149.     {
  150.         delta[i] = xvec[i]*(x - pressx) + yvec[i]*(y - pressy);
  151.         delta[i] = floor(delta[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  152.     }
  153.     VectorSubtract (delta, pressdelta, move);
  154.     VectorCopy (delta, pressdelta);
  155.  
  156.     if (move[0] || move[1] || move[2])
  157.         return true;
  158.     return false;
  159. }
  160.  
  161. /*
  162. ==============
  163. NewBrushDrag
  164. ==============
  165. */
  166. void NewBrushDrag (int x, int y)
  167. {
  168.     vec3_t    mins, maxs, junk;
  169.     int        i;
  170.     float    temp;
  171.     brush_t    *n;
  172.  
  173.     if (!DragDelta (x,y, junk))
  174.         return;
  175.     // delete the current selection
  176.     if (selected_brushes.next != &selected_brushes)
  177.         Brush_Free (selected_brushes.next);
  178.     XY_ToGridPoint (pressx, pressy, mins);
  179.     mins[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom_z/g_qeglobals.d_gridsize));
  180.     XY_ToGridPoint (x, y, maxs);
  181.     maxs[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top_z/g_qeglobals.d_gridsize));
  182.     if (maxs[2] <= mins[2])
  183.         maxs[2] = mins[2] + g_qeglobals.d_gridsize;
  184.  
  185.     for (i=0 ; i<3 ; i++)
  186.     {
  187.         if (mins[i] == maxs[i])
  188.             return;    // don't create a degenerate brush
  189.         if (mins[i] > maxs[i])
  190.         {
  191.             temp = mins[i];
  192.             mins[i] = maxs[i];
  193.             maxs[i] = temp;
  194.         }
  195.     }
  196.  
  197.     n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef);
  198.     if (!n)
  199.         return;
  200.  
  201.     Brush_AddToList (n, &selected_brushes);
  202.  
  203.     Entity_LinkBrush (world_entity, n);
  204.  
  205.     Brush_Build( n );
  206.  
  207. //    Sys_UpdateWindows (W_ALL);
  208.     Sys_UpdateWindows (W_XY| W_CAMERA);
  209. }
  210.  
  211. /*
  212. ==============
  213. XY_MouseMoved
  214. ==============
  215. */
  216. void XY_MouseMoved (int x, int y, int buttons)
  217. {
  218.     vec3_t    point;
  219.  
  220.     if (!buttonstate)
  221.         return;
  222.  
  223.     // lbutton without selection = drag new brush
  224.     if (buttonstate == MK_LBUTTON && !press_selection)
  225.     {
  226.         NewBrushDrag (x, y);
  227.         return;
  228.     }
  229.  
  230.     // lbutton (possibly with control and or shift)
  231.     // with selection = drag selection
  232.     if (buttonstate & MK_LBUTTON)
  233.     {
  234.         Drag_MouseMoved (x, y, buttons);
  235.         Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA);
  236.         return;
  237.     }
  238.  
  239.     // control mbutton = move camera
  240.     if (buttonstate == (MK_CONTROL|MK_MBUTTON) )
  241.     {
  242.         XY_ToPoint (x, y, point);
  243.         camera.origin[0] = point[0];
  244.         camera.origin[1] = point[1];
  245.         Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA);
  246.         return;
  247.     }
  248.  
  249.     // shift mbutton = move z checker
  250.     if (buttonstate == (MK_SHIFT|MK_MBUTTON) )
  251.     {
  252.         XY_ToPoint (x, y, point);
  253.         z.origin[0] = point[0];
  254.         z.origin[1] = point[1];
  255.         Sys_UpdateWindows (W_XY_OVERLAY|W_Z);
  256.         return;
  257.     }
  258.  
  259.     // mbutton = angle camera
  260.     if (buttonstate == MK_MBUTTON )
  261.     {    
  262.         XY_ToPoint (x, y, point);
  263.         VectorSubtract (point, camera.origin, point);
  264.         if (point[1] || point[0])
  265.         {
  266.             camera.angles[YAW] = 180/Q_PI*atan2 (point[1], point[0]);
  267.             Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA);
  268.         }
  269.         return;
  270.     }
  271.  
  272.     // rbutton = drag xy origin
  273.     if (buttonstate == MK_RBUTTON)
  274.     {
  275.         Sys_GetCursorPos (&x, &y);
  276.         if (x != cursorx || y != cursory)
  277.         {
  278.             g_qeglobals.d_xy.origin[0] -= (x-cursorx)/g_qeglobals.d_xy.scale;
  279.             g_qeglobals.d_xy.origin[1] += (y-cursory)/g_qeglobals.d_xy.scale;
  280.             Sys_SetCursorPos (cursorx, cursory);
  281.             Sys_UpdateWindows (W_XY | W_XY_OVERLAY);
  282.         }
  283.         return;
  284.     }
  285. }
  286.  
  287.  
  288. /*
  289. ============================================================================
  290.  
  291. DRAWING
  292.  
  293. ============================================================================
  294. */
  295.  
  296.  
  297. /*
  298. ==============
  299. XY_DrawGrid
  300. ==============
  301. */
  302. void XY_DrawGrid (void)
  303. {
  304.     float    x, y, xb, xe, yb, ye;
  305.     int        w, h;
  306.     char    text[32];
  307.  
  308.     glDisable(GL_TEXTURE_2D);
  309.     glDisable(GL_TEXTURE_1D);
  310.     glDisable(GL_DEPTH_TEST);
  311.     glDisable(GL_BLEND);
  312.  
  313.     w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
  314.     h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
  315.  
  316.     xb = g_qeglobals.d_xy.origin[0] - w;
  317.     if (xb < region_mins[0])
  318.         xb = region_mins[0];
  319.     xb = 64 * floor (xb/64);
  320.  
  321.     xe = g_qeglobals.d_xy.origin[0] + w;
  322.     if (xe > region_maxs[0])
  323.         xe = region_maxs[0];
  324.     xe = 64 * ceil (xe/64);
  325.  
  326.     yb = g_qeglobals.d_xy.origin[1] - h;
  327.     if (yb < region_mins[1])
  328.         yb = region_mins[1];
  329.     yb = 64 * floor (yb/64);
  330.  
  331.     ye = g_qeglobals.d_xy.origin[1] + h;
  332.     if (ye > region_maxs[1])
  333.         ye = region_maxs[1];
  334.     ye = 64 * ceil (ye/64);
  335.  
  336.     // draw major blocks
  337.  
  338.     glColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR]);
  339.  
  340.     if ( g_qeglobals.d_showgrid )
  341.     {
  342.         
  343.         glBegin (GL_LINES);
  344.         
  345.         for (x=xb ; x<=xe ; x+=64)
  346.         {
  347.             glVertex2f (x, yb);
  348.             glVertex2f (x, ye);
  349.         }
  350.         for (y=yb ; y<=ye ; y+=64)
  351.         {
  352.             glVertex2f (xb, y);
  353.             glVertex2f (xe, y);
  354.         }
  355.         
  356.         glEnd ();
  357.         
  358.     }
  359.  
  360.     // draw minor blocks
  361.     if ( g_qeglobals.d_showgrid && g_qeglobals.d_gridsize*g_qeglobals.d_xy.scale >= 4)
  362.     {
  363.         glColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR]);
  364.  
  365.         glBegin (GL_LINES);
  366.         for (x=xb ; x<xe ; x += g_qeglobals.d_gridsize)
  367.         {
  368.             if ( ! ((int)x & 63) )
  369.                 continue;
  370.             glVertex2f (x, yb);
  371.             glVertex2f (x, ye);
  372.         }
  373.         for (y=yb ; y<ye ; y+=g_qeglobals.d_gridsize)
  374.         {
  375.             if ( ! ((int)y & 63) )
  376.                 continue;
  377.             glVertex2f (xb, y);
  378.             glVertex2f (xe, y);
  379.         }
  380.         glEnd ();
  381.     }
  382.  
  383.     // draw coordinate text if needed
  384.  
  385.     if ( g_qeglobals.d_savedinfo.show_coordinates)
  386.     {
  387.         glColor4f(0, 0, 0, 0);
  388.  
  389.         for (x=xb ; x<xe ; x+=64)
  390.         {
  391.             glRasterPos2f (x, g_qeglobals.d_xy.origin[1] + h - 6/g_qeglobals.d_xy.scale);
  392.             sprintf (text, "%i",(int)x);
  393.             glCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
  394.         }
  395.         for (y=yb ; y<ye ; y+=64)
  396.         {
  397.             glRasterPos2f (g_qeglobals.d_xy.origin[0] - w + 1, y);
  398.             sprintf (text, "%i",(int)y);
  399.             glCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
  400.         }
  401.     }
  402. }
  403.  
  404. /*
  405. ==============
  406. XY_DrawBlockGrid
  407. ==============
  408. */
  409. void XY_DrawBlockGrid (void)
  410. {
  411.     float    x, y, xb, xe, yb, ye;
  412.     int        w, h;
  413.     char    text[32];
  414.  
  415.     glDisable(GL_TEXTURE_2D);
  416.     glDisable(GL_TEXTURE_1D);
  417.     glDisable(GL_DEPTH_TEST);
  418.     glDisable(GL_BLEND);
  419.  
  420.     w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
  421.     h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
  422.  
  423.     xb = g_qeglobals.d_xy.origin[0] - w;
  424.     if (xb < region_mins[0])
  425.         xb = region_mins[0];
  426.     xb = 1024 * floor (xb/1024);
  427.  
  428.     xe = g_qeglobals.d_xy.origin[0] + w;
  429.     if (xe > region_maxs[0])
  430.         xe = region_maxs[0];
  431.     xe = 1024 * ceil (xe/1024);
  432.  
  433.     yb = g_qeglobals.d_xy.origin[1] - h;
  434.     if (yb < region_mins[1])
  435.         yb = region_mins[1];
  436.     yb = 1024 * floor (yb/1024);
  437.  
  438.     ye = g_qeglobals.d_xy.origin[1] + h;
  439.     if (ye > region_maxs[1])
  440.         ye = region_maxs[1];
  441.     ye = 1024 * ceil (ye/1024);
  442.  
  443.     // draw major blocks
  444.  
  445.     glColor3f(0,0,1);
  446.     glLineWidth (2);
  447.  
  448.     glBegin (GL_LINES);
  449.     
  450.     for (x=xb ; x<=xe ; x+=1024)
  451.     {
  452.         glVertex2f (x, yb);
  453.         glVertex2f (x, ye);
  454.     }
  455.     for (y=yb ; y<=ye ; y+=1024)
  456.     {
  457.         glVertex2f (xb, y);
  458.         glVertex2f (xe, y);
  459.     }
  460.     
  461.     glEnd ();
  462.     glLineWidth (1);
  463.  
  464.     // draw coordinate text if needed
  465.  
  466.     for (x=xb ; x<xe ; x+=1024)
  467.         for (y=yb ; y<ye ; y+=1024)
  468.         {
  469.             glRasterPos2f (x+512, y+512);
  470.             sprintf (text, "%i,%i",(int)floor(x/1024), (int)floor(y/1024) );
  471.             glCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
  472.         }
  473.  
  474.     glColor4f(0, 0, 0, 0);
  475. }
  476.  
  477.  
  478. void DrawCameraIcon (void)
  479. {
  480.     float    x, y, a;
  481.  
  482.     x = camera.origin[0];
  483.     y = camera.origin[1];
  484.     a = camera.angles[YAW]/180*Q_PI;
  485.  
  486.     glColor3f (0.0, 0.0, 1.0);
  487.     glBegin(GL_LINE_STRIP);
  488.     glVertex3f (x-16,y,0);
  489.     glVertex3f (x,y+8,0);
  490.     glVertex3f (x+16,y,0);
  491.     glVertex3f (x,y-8,0);
  492.     glVertex3f (x-16,y,0);
  493.     glVertex3f (x+16,y,0);
  494.     glEnd ();
  495.     
  496.     glBegin(GL_LINE_STRIP);
  497.     glVertex3f (x+48*cos(a+Q_PI/4), y+48*sin(a+Q_PI/4), 0);
  498.     glVertex3f (x, y, 0);
  499.     glVertex3f (x+48*cos(a-Q_PI/4), y+48*sin(a-Q_PI/4), 0);
  500.     glEnd ();
  501.  
  502. }
  503.  
  504. void DrawZIcon (void)
  505. {
  506.     float    x, y;
  507.  
  508.     x = z.origin[0];
  509.     y = z.origin[1];
  510.  
  511.     glEnable (GL_BLEND);
  512.     glDisable (GL_TEXTURE_2D);
  513.     glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  514.     glDisable (GL_CULL_FACE);
  515.     glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  516.     glColor4f (0.0, 0.0, 1.0, 0.25);
  517.     glBegin(GL_QUADS);
  518.     glVertex3f (x-8,y-8,0);
  519.     glVertex3f (x+8,y-8,0);
  520.     glVertex3f (x+8,y+8,0);
  521.     glVertex3f (x-8,y+8,0);
  522.     glEnd ();
  523.     glDisable (GL_BLEND);
  524.  
  525.     glColor4f (0.0, 0.0, 1.0, 1);
  526.  
  527.     glBegin(GL_LINE_LOOP);
  528.     glVertex3f (x-8,y-8,0);
  529.     glVertex3f (x+8,y-8,0);
  530.     glVertex3f (x+8,y+8,0);
  531.     glVertex3f (x-8,y+8,0);
  532.     glEnd ();
  533.  
  534.     glBegin(GL_LINE_STRIP);
  535.     glVertex3f (x-4,y+4,0);
  536.     glVertex3f (x+4,y+4,0);
  537.     glVertex3f (x-4,y-4,0);
  538.     glVertex3f (x+4,y-4,0);
  539.     glEnd ();
  540. }
  541.  
  542.  
  543. /*
  544. ==================
  545. FilterBrush
  546. ==================
  547. */
  548. BOOL FilterBrush(brush_t *pb)
  549. {
  550.     if (!pb->owner)
  551.         return FALSE;        // during construction
  552.  
  553.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP)
  554.     {
  555.         if (!strncmp(pb->brush_faces->texdef.name, "clip", 4))
  556.             return TRUE;
  557.     }
  558.  
  559.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WATER)
  560.     {
  561.         if (pb->brush_faces->texdef.name[0] == '*')
  562.             return TRUE;
  563.     }
  564.  
  565.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DETAIL)
  566.     {
  567.         if (pb->brush_faces->texdef.contents & CONTENTS_DETAIL)
  568.             return TRUE;
  569.     }
  570.  
  571.     if (pb->owner == world_entity)
  572.     {
  573.         if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD)
  574.             return TRUE;
  575.         return FALSE;
  576.     }
  577.     else if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT)
  578.         return TRUE;
  579.     
  580.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS)
  581.     {
  582.         if (!strncmp(pb->owner->eclass->name, "light", 5))
  583.             return TRUE;
  584.     }
  585.  
  586.     if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS)
  587.     {
  588.         if (!strncmp(pb->owner->eclass->name, "path", 4))
  589.             return TRUE;
  590.     }
  591.  
  592.     return FALSE;
  593. }
  594.  
  595. /*
  596. =============================================================
  597.  
  598.   PATH LINES
  599.  
  600. =============================================================
  601. */
  602.  
  603. /*
  604. ==================
  605. DrawPathLines
  606.  
  607. Draws connections between entities.
  608. Needs to consider all entities, not just ones on screen,
  609. because the lines can be visible when neither end is.
  610. Called for both camera view and xy view.
  611. ==================
  612. */
  613. void DrawPathLines (void)
  614. {
  615.     int        i, j, k;
  616.     vec3_t    mid, mid1;
  617.     entity_t *se, *te;
  618.     brush_t    *sb, *tb;
  619.     char    *psz;
  620.     vec3_t    dir, s1, s2;
  621.     vec_t    len, f;
  622.     int        arrows;
  623.     int            num_entities;
  624.     char        *ent_target[MAX_MAP_ENTITIES];
  625.     entity_t    *ent_entity[MAX_MAP_ENTITIES];
  626.  
  627.  
  628.     num_entities = 0;
  629.     for (te = entities.next ; te != &entities && num_entities != MAX_MAP_ENTITIES ; te = te->next)
  630.     {
  631.         ent_target[num_entities] = ValueForKey (te, "target");
  632.         if (ent_target[num_entities][0])
  633.         {
  634.             ent_entity[num_entities] = te;
  635.             num_entities++;
  636.         }
  637.     }
  638.  
  639.     for (se = entities.next ; se != &entities ; se = se->next)
  640.     {
  641.         psz = ValueForKey(se, "targetname");
  642.     
  643.         if (psz == NULL || psz[0] == '\0')
  644.             continue;
  645.         
  646.         sb = se->brushes.onext;
  647.         if (sb == &se->brushes)
  648.             continue;
  649.  
  650.         for (k=0 ; k<num_entities ; k++)
  651.         {
  652.             if (strcmp (ent_target[k], psz))
  653.                 continue;
  654.  
  655.             te = ent_entity[k];
  656.             tb = te->brushes.onext;
  657.             if (tb == &te->brushes)
  658.                 continue;
  659.  
  660.             for (i=0 ; i<3 ; i++)
  661.                 mid[i] = (sb->mins[i] + sb->maxs[i])*0.5; 
  662.  
  663.             for (i=0 ; i<3 ; i++)
  664.                 mid1[i] = (tb->mins[i] + tb->maxs[i])*0.5; 
  665.  
  666.             VectorSubtract (mid1, mid, dir);
  667.             len = VectorNormalize (dir);
  668.             s1[0] = -dir[1]*8 + dir[0]*8;
  669.             s2[0] = dir[1]*8 + dir[0]*8;
  670.             s1[1] = dir[0]*8 + dir[1]*8;
  671.             s2[1] = -dir[0]*8 + dir[1]*8;
  672.  
  673.             glColor3f (se->eclass->color[0], se->eclass->color[1], se->eclass->color[2]);
  674.  
  675.             glBegin(GL_LINES);
  676.             glVertex3fv(mid);
  677.             glVertex3fv(mid1);
  678.  
  679.             arrows = (int)(len / 256) + 1;
  680.  
  681.             for (i=0 ; i<arrows ; i++)
  682.             {
  683.                 f = len * (i + 0.5) / arrows;
  684.  
  685.                 for (j=0 ; j<3 ; j++)
  686.                     mid1[j] = mid[j] + f*dir[j];
  687.                 glVertex3fv (mid1);
  688.                 glVertex3f (mid1[0] + s1[0], mid1[1] + s1[1], mid1[2]);
  689.                 glVertex3fv (mid1);
  690.                 glVertex3f (mid1[0] + s2[0], mid1[1] + s2[1], mid1[2]);
  691.             }
  692.  
  693.             glEnd();
  694.         }
  695.     }
  696.  
  697.     return;
  698. }
  699.  
  700. //=============================================================
  701.  
  702.  
  703. /*
  704. ==============
  705. XY_Draw
  706. ==============
  707. */
  708. void XY_Draw (void)
  709. {
  710.     brush_t    *brush;
  711.     float    w, h;
  712.     entity_t    *e;
  713.     double    start, end;
  714.     vec3_t    mins, maxs;
  715.     int        drawn, culled;
  716.     int        i;
  717.  
  718.     if (!active_brushes.next)
  719.         return;    // not valid yet
  720.  
  721.     if (g_qeglobals.d_xy.timing)
  722.         start = Sys_DoubleTime ();
  723.  
  724.     //
  725.     // clear
  726.     //
  727.     g_qeglobals.d_xy.d_dirty = false;
  728.  
  729.     glViewport(0, 0, g_qeglobals.d_xy.width, g_qeglobals.d_xy.height);
  730.     glClearColor (
  731.         g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0],
  732.         g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1],
  733.         g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2],
  734.         0);
  735.  
  736.     glClear(GL_COLOR_BUFFER_BIT);
  737.  
  738.     //
  739.     // set up viewpoint
  740.     //
  741.     glMatrixMode(GL_PROJECTION);
  742.     glLoadIdentity ();
  743.  
  744.     w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
  745.     h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
  746.     mins[0] = g_qeglobals.d_xy.origin[0] - w;
  747.     maxs[0] = g_qeglobals.d_xy.origin[0] + w;
  748.     mins[1] = g_qeglobals.d_xy.origin[1] - h;
  749.     maxs[1] = g_qeglobals.d_xy.origin[1] + h;
  750.  
  751.     glOrtho (mins[0], maxs[0], mins[1], maxs[1], -8000, 8000);
  752.  
  753.     //
  754.     // now draw the grid
  755.     //
  756.     XY_DrawGrid ();
  757.  
  758.     //
  759.     // draw stuff
  760.     //
  761.     glShadeModel (GL_FLAT);
  762.     glDisable(GL_TEXTURE_2D);
  763.     glDisable(GL_TEXTURE_1D);
  764.     glDisable(GL_DEPTH_TEST);
  765.     glDisable(GL_BLEND);
  766.     glColor3f(0, 0, 0);
  767. //        glEnable (GL_LINE_SMOOTH);
  768.  
  769.     drawn = culled = 0;
  770.  
  771.     e = NULL;
  772.     for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
  773.     {
  774.         if (brush->mins[0] > maxs[0]
  775.             || brush->mins[1] > maxs[1]
  776.             || brush->maxs[0] < mins[0]
  777.             || brush->maxs[1] < mins[1]    )
  778.         {
  779.             culled++;
  780.             continue;        // off screen
  781.         }
  782.  
  783.         if (FilterBrush (brush))
  784.             continue;
  785.         drawn++;
  786.         if (brush->owner != e)
  787.         {
  788.             e = brush->owner;
  789.             glColor3fv(e->eclass->color);
  790.         }
  791.         Brush_DrawXY( brush );
  792.     }
  793.  
  794.     DrawPathLines ();
  795.  
  796.     //
  797.     // draw pointfile
  798.     //
  799.     if ( g_qeglobals.d_pointfile_display_list)
  800.         glCallList (g_qeglobals.d_pointfile_display_list);
  801.  
  802.     //
  803.     // draw block grid
  804.     //
  805.     if ( g_qeglobals.show_blocks)
  806.         XY_DrawBlockGrid ();
  807.  
  808.     //
  809.     // now draw selected brushes
  810.     //
  811.     glTranslatef( g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);
  812.  
  813.     glColor3f(1.0, 0.0, 0.0);
  814.     glEnable (GL_LINE_STIPPLE);
  815.     glLineStipple (3, 0xaaaa);
  816.     glLineWidth (2);
  817.  
  818.     for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
  819.     {
  820.         drawn++;
  821.         Brush_DrawXY( brush );
  822.     }
  823.  
  824.     glDisable (GL_LINE_STIPPLE);
  825.     glLineWidth (1);
  826.  
  827.     // edge / vertex flags
  828.  
  829.     if (g_qeglobals.d_select_mode == sel_vertex)
  830.     {
  831.         glPointSize (4);
  832.         glColor3f (0,1,0);
  833.         glBegin (GL_POINTS);
  834.         for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
  835.             glVertex3fv (g_qeglobals.d_points[i]);
  836.         glEnd ();
  837.         glPointSize (1);
  838.     }
  839.     else if (g_qeglobals.d_select_mode == sel_edge)
  840.     {
  841.         float    *v1, *v2;
  842.  
  843.         glPointSize (4);
  844.         glColor3f (0,0,1);
  845.         glBegin (GL_POINTS);
  846.         for (i=0 ; i<g_qeglobals.d_numedges ; i++)
  847.         {
  848.             v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
  849.             v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
  850.             glVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
  851.         }
  852.         glEnd ();
  853.         glPointSize (1);
  854.     }
  855.     glTranslatef (-g_qeglobals.d_select_translate[0], -g_qeglobals.d_select_translate[1], -g_qeglobals.d_select_translate[2]);
  856.  
  857.     //
  858.     // now draw camera point
  859.     //
  860.     DrawCameraIcon ();
  861.     DrawZIcon ();
  862.  
  863.     glFinish();
  864.     QE_CheckOpenGLForErrors();
  865.  
  866.     if (g_qeglobals.d_xy.timing)
  867.     {
  868.         end = Sys_DoubleTime ();
  869.         Sys_Printf ("xy: %i ms\n", (int)(1000*(end-start)));
  870.     }
  871. }
  872.  
  873. /*
  874. ==============
  875. XY_Overlay
  876. ==============
  877. */
  878. void XY_Overlay (void)
  879. {
  880.     int    w, h;
  881.     int    r[4];
  882.     static    vec3_t    lastz;
  883.     static    vec3_t    lastcamera;
  884.  
  885.  
  886.     glViewport(0, 0, g_qeglobals.d_xy.width, g_qeglobals.d_xy.height);
  887.  
  888.     //
  889.     // set up viewpoint
  890.     //
  891.     glMatrixMode(GL_PROJECTION);
  892.     glLoadIdentity ();
  893.  
  894.     w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
  895.     h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
  896.     glOrtho (g_qeglobals.d_xy.origin[0] - w, g_qeglobals.d_xy.origin[0] + w
  897.         , g_qeglobals.d_xy.origin[1] - h, g_qeglobals.d_xy.origin[1] + h, -8000, 8000);
  898.     //
  899.     // erase the old camera and z checker positions
  900.     // if the entire xy hasn't been redrawn
  901.     //
  902.     if (g_qeglobals.d_xy.d_dirty)
  903.     {
  904.         glReadBuffer (GL_BACK);
  905.         glDrawBuffer (GL_FRONT);
  906.  
  907.         glRasterPos2f (lastz[0]-9, lastz[1]-9);
  908.         glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  909.         glCopyPixels(r[0], r[1], 18,18, GL_COLOR);
  910.  
  911.         glRasterPos2f (lastcamera[0]-50, lastcamera[1]-50);
  912.         glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  913.         glCopyPixels(r[0], r[1], 100,100, GL_COLOR);
  914.     }
  915.     g_qeglobals.d_xy.d_dirty = true;
  916.  
  917.     //
  918.     // save off underneath where we are about to draw
  919.     //
  920.     VectorCopy (z.origin, lastz);
  921.     VectorCopy (camera.origin, lastcamera);
  922.  
  923.     glReadBuffer (GL_FRONT);
  924.     glDrawBuffer (GL_BACK);
  925.  
  926.     glRasterPos2f (lastz[0]-9, lastz[1]-9);
  927.     glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  928.     glCopyPixels(r[0], r[1], 18,18, GL_COLOR);
  929.  
  930.     glRasterPos2f (lastcamera[0]-50, lastcamera[1]-50);
  931.     glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  932.     glCopyPixels(r[0], r[1], 100,100, GL_COLOR);
  933.  
  934.     //
  935.     // draw the new icons
  936.     //
  937.     glDrawBuffer (GL_FRONT);
  938.  
  939.     glShadeModel (GL_FLAT);
  940.     glDisable(GL_TEXTURE_2D);
  941.     glDisable(GL_TEXTURE_1D);
  942.     glDisable(GL_DEPTH_TEST);
  943.     glDisable(GL_BLEND);
  944.     glColor3f(0, 0, 0);
  945.  
  946.     DrawCameraIcon ();
  947.     DrawZIcon ();
  948.  
  949.     glDrawBuffer (GL_BACK);
  950.     glFinish();
  951. }
  952.  
  953.